/*
 * Copyright (c) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.api.client.generator.discovery;

import com.google.api.client.generator.common.java.AbstractJavaFileGenerator;
import com.google.api.client.generator.discovery.model.ClassModel;
import com.google.api.client.generator.discovery.model.PropertyModel;
import com.google.api.client.generator.discovery.model.SchemaBasedModel;
import com.google.api.client.generator.discovery.model.ServiceModel;
import com.google.api.client.util.DateTime;

import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.List;

/**
 * @author yanivi@google.com (Your Name Here)
 *
 */
abstract class AbstractDiscoveryJavaFileGenerator extends AbstractJavaFileGenerator {

  AbstractDiscoveryJavaFileGenerator(ServiceModel service, String packageName, String className) {
    super(
        service.getName() + "/" + service.getVersion() + "/src/main/java/", packageName, className);
  }

  final void writeJavaDoc(PrintWriter out, int indentNumSpaces, SchemaBasedModel schemaBased) {
    writeJavaDoc(out, indentNumSpaces, schemaBased.getDescription());
  }

  final String useType(SchemaBasedModel schemaBased) {
    if (schemaBased instanceof ClassModel) {
      return useClass(((ClassModel) schemaBased).getFullName());
    }
    switch (schemaBased.getType()) {
      case ANY:
        return useClass(Object.class);
      case STRING:
        return useClass(String.class);
      case BOOLEAN:
        return useClass(Boolean.class);
      case DATE_TIME:
        return useClass(DateTime.class);
      case UINT32:
        // TODO(yanivi): UnsignedInteger?
      case INT64:
        return useClass(Long.class);
      case UINT64:
        // TODO(yanivi): UnsignedLong?
        return useClass(BigInteger.class);
      case FLOAT:
        return useClass(Float.class);
      case DOUBLE:
        return useClass(Double.class);
      case INT16:
        return useClass(Short.class);
      case INT32:
        return useClass(Integer.class);
      case REF:
        return useType(schemaBased.getRef());
      case ARRAY:
        StringBuilder builder = new StringBuilder();
        PropertyModel property = (PropertyModel) schemaBased;
        int count = property.getArrayCount();
        for (int i = 0; i < count; i++) {
          builder.append(useClass(List.class)).append("<");
        }
        builder.append(useType(property.getArray()));
        for (int i = 0; i < count; i++) {
          builder.append(">");
        }
        return builder.toString();
      case OBJECT:
        return useType(((PropertyModel) schemaBased).getObject());
      default:
        throw new IllegalArgumentException(schemaBased.getType().toString());
    }
  }
}
